﻿namespace LoveMusic.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Transactions;
    using System.Xml.Linq;
    using LoveMusic;
    using LoveMusic.Helpers;

    /// <summary>
    /// Linq to Sql implementation of <see cref="IDataContext"/>.
    /// </summary>
    /// 

    public partial class ModelDataContext : IDataContext
    {
        #region const

        private const int totalLimit = 100;
        private const int numNewPages = 3;
        partial void OnCreated()
        {
            //Put your desired timeout here.
#if (DEBUG )

            this.CommandTimeout = 60;
#else
            this.CommandTimeout = 35;
#endif
            //If you do not want to hard code it, then take it 
            //from Application Settings / AppSettings
            //this.CommandTimeout = Settings.Default.CommandTimeout;
        }

        #endregion

        #region Categories


        /// <summary>
        /// Gets the categories.
        /// </summary>
        /// <returns></returns>
        public Category[] GetCategories()
        {
            return Categories.OrderBy(c => c.ID).ToArray();
        }

        /// <summary>
        /// Gets the category for the specified name.
        /// </summary>
        /// <param name="categoryName">Name of the category.</param>
        /// <returns></returns>
        public Category GetCategoryByName(string categoryName)
        {
            return Categories.FirstOrDefault(c => c.Name == categoryName);
        }

        /// <summary>
        /// Gets the published stories for all category.
        /// Use the store procedure.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetSongsForAllCategory(Guid userId, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in fnGetSongs() on s.ID equals fts.ID
                          select s;

            total = stories.Count();

            var returnStories = PrepareStories(
                                        stories,
                                        userId,
                                        start,
                                        max
                                    );
            return returnStories;
        }

        /// <summary>
        /// Gets the published stories for all moods on category
        /// Use the store procedure.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetSongsMoodsCategory(string moodList, Guid userId, int categoryId, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in fnGetSongsForMoodsForCategory(moodList, categoryId) on s.ID equals fts.ID
                          select s;

            //total = stories.Count();
            total = totalLimit;

            var returnStories = PrepareStoriesForMoods(
                                        stories,
                                        userId
                                    );

            return returnStories;
        }


        /// <summary>
        /// Gets the published stories for all moods.
        /// Use the store procedure.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] SearchMoods(string moodList, int weight, Guid userId, int skip, int take, out int total)
        {
            var stories = from s in Stories
                          join fts in fnMoodSong(moodList, weight) on s.ID equals fts.ID
                          select s;

            total = totalLimit;

            var returnStories = PrepareStoriesForMoods(
                                        stories,
                                        userId,
                                        take,
                                        skip
                                    ).OrderByDescending(s => s.Playcount).ToArray();

            return returnStories;
        }

        /// <summary>
        /// Gets the published stories for all moods.
        /// Use the store procedure.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] SearchMoodsVideo(string moodList, int weight, Guid userId, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in fnGetSongsForMoodsSearchType(moodList, weight) on s.ID equals fts.ID
                          select s;

            total = totalLimit;

            var returnStories = PrepareStoriesForMoods(
                                        stories,
                                        userId
                                    );

            return returnStories;
        }

        private static int GetTotal(int start, int total)
        {
            if (start + 10 + (numNewPages * 10) > total)
                return total;
            if (start >= totalLimit - 10)
                total = start + 10 + (numNewPages * 10);
            else
                if (total > totalLimit)
                    total = totalLimit;
            return total;
        }

        /// <summary>
        /// Gets the published stories for the specified category.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetSongsForCategory(Guid userId, int categoryId, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in fnGetSongsForCategory(categoryId, Stories.Where(s => s.CategoryID == categoryId && s.Playcount > 10).Count() / 2) on s.ID equals fts.ID
                          select s;

            total = stories.Count();

            return PrepareStories(
                                        stories,
                                        userId,
                                        start,
                                        max
                                    );
        }

        #endregion Categories

        #region CMS
        /// <summary>
        /// Returns the html value for the cms of the according type (tip)
        /// </summary>
        /// <param name="tip"></param>
        /// <returns></returns>
        public String GetValue(string tip)
        {
            CM cms = CMs.Single(p => p.Tip == tip);
            return cms.Value.ToString();
        }

        /// <summary>
        /// CMS 
        /// </summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        public void SubmitText(string type, string value)
        {
            // value type = "studio"
            // value example = " html goes here"
            CM cms = CMs.Single(p => p.Tip == type);
            cms.Value = value;
            SubmitChanges();
        }


        #endregion CMS

        #region Tags
        /// <summary>
        /// Gets the tag for the specified name.
        /// </summary>
        /// <param name="tagName">Name of the tag.</param>
        /// <returns></returns>
        public Tag GetTagByName(string tagName)
        {
            return Tags.FirstOrDefault(t => t.Name == tagName);
        }

        /// <summary>
        /// Gets the top tags.
        /// </summary>
        /// <param name="top">The number of top tags.</param>
        /// <returns></returns>
        public TagItem[] GetTags(int top)
        {
            return Tags
                        .Select
                        (
                           t =>
                           new TagItem
                           {
                               ID = t.ID,
                               Name = t.Name,
                               //Count = t.StoryTags.Count()
                           }
                        )
                //.OrderByDescending(t => t.Count)
                //.ThenBy(t => t.Name)
                        .Take(top)
                        .ToArray();
        }


        public StoryListItem[] GetStoriesForTag(Guid userId, string tagName, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in TagSearch(tagName) on s.ID equals fts.ID
                          select s;

            total = totalLimit;

            return PrepareStories(
                                    stories,
                                    userId,
                                    start,
                                    max
                                );
        }
        /// <summary>
        /// Gets the stories for the specified tag.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="tagId">The tag id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetStoriesForTag(Guid userId, int tagId, int start, int max, out int total)
        {
            //var stories = from s in Stories
            //              join fts in music_sessionSearch(query) on s.ID equals fts.KEY
            //              select s;



            var stories = Stories.Where(s => s.StoryTags.Count(st => st.TagID == tagId) > 0);

            total = totalLimit;
            //total = stories.Count();

            //total = GetTotal(start, total);
            //The Published will appear first
            return PrepareStories(
                                    stories,
                                    userId,
                                    start,
                                    max
                                );
        }



        #endregion Tags

        #region Top10

        /// <summary>
        /// Gets the 10 most voted published stories for all category in last 7 days 
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetTop10All(Guid userId, int start, int max, out int total)
        {
            DateTime dateNow = DateTime.Now.Date;
            DateTime dateBefore7Days = dateNow.AddDays(-7.0);
            var stories = Stories.Where(s => (s.PublishedOn != null) && ((DateTime.Compare(dateBefore7Days, s.PublishedOn.Value) < 0)));
            total = stories.Count();
            return PrepareStoriesForTop10(
                                        stories
                                        .OrderByDescending(s => s.PublishedOn),
                                        userId,
                                        start,
                                        max
                                    );
        }
        /// <summary>
        /// Gets the 10 most voted published stories for a specific category in last 7 days 
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetTop10Category(Guid userId, int categoryId, int start, int max, out int total)
        {
            var stories = Stories.Where(s => (s.PublishedOn != null) && (s.CategoryID == categoryId));
            total = stories.Count();

            return PrepareStoriesForTop10(
                                        stories,
                                        userId,
                                        start,
                                        max
                                    );
        }


        /// <summary>
        /// Gets the Top10 upcoming stories for last 7 days
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetUpcomingStoriesTop10(Guid userId, int start, int max)
        {
            var stories = Stories.Where(s => s.PublishedOn == null);

            return PrepareStoriesForTop10(stories,
                                    userId,
                                    start,
                                    max
                                );
        }

        #endregion Top10

        #region Story

        public List<CloudHolder> Get50Songs()
        {
            Random r = new Random();
            int randBroj = r.Next(1, 1000000);
            return
                Stories.
                        Select(s => new CloudHolder
                        {
                            id = s.ID,
                            mood = s.Title,
                            counter = (int?)s.Playcount
                        })
                        .Where(s => s.id > randBroj && s.counter > 10000)
                        .Take(50)
                        .ToList();
        }

        /// <summary>
        /// Gets the story detail by id.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="storyId">The story id.</param>
        /// <returns></returns>
        public StoryDetailItem Detail(Guid userId, int storyId)
        {
            // GoogleAPI googleApi = new GoogleAPI();

            var song = Stories
                               .Where(s => s.ID == storyId)
                               .Select(s =>
                                        new StoryDetailItem
                                        {
                                            ID = s.ID,
                                            Title = s.Title,
                                            Description = s.Description,
                                            YouTubeDescription = s.youTubeDescription,
                                            ArtistName = s.ArtistName,
                                            ArtistID = s.ARTIST_IDZ,
                                            Category = s.Category.Name,
                                            Tags = s.StoryTags.Select(st => st.Tag.Name).ToArray(),
                                            YouTubeID = s.YouTubeID,
                                            PostedBy = new UserItem
                                            {
                                                Name = s.PostedByUserName,
                                            },
                                            PostedOn = s.PostedOn,
                                            PublishedOn = s.PublishedOn,
                                            VoteCount = s.Votes.Count(),
                                            HasVoted = (s.Votes.Count(v => v.UserID == userId) > 0),
                                            ImageID = (int?)s.ARTIST.IMAGEs
                                                                .Where(im => im.ARTIST_IDZ == s.ARTIST_IDZ)
                                                                .First()
                                                                .IMAGE_IDZ ?? 0,
                                            Mp3Files = s.MP3FILEs
                                                            .Where(v => v.IsValid == true)
                                                            .Select(v => new Mp3FileItem
                                                                                        {
                                                                                            Url = v.url,
                                                                                            UrlHandler = "/Song/GetStreamMp3/" + v.MP3_FILEIDZ.ToString() + "/" + s.ID.ToString(),
                                                                                            Mp3File_ID = v.MP3_FILEIDZ,
                                                                                            Story_ID = v.Story_ID,
                                                                                            Title = v.Title
                                                                                        }
                                                                        )
                                                            .ToArray(),
                                            VotedBy = s.Votes
                                                            .OrderBy(v => v.Timestamp)
                                                            .Select(v =>
                                                                        new UserItem
                                                                        {
                                                                            Name = v.aspnet_User.UserName

                                                                        }
                                                                    )
                                                                    .ToArray(),
                                            Comments = s.Comments
                                                                .OrderBy(c => c.PostedOn)
                                                                .Select(c =>
                                                                            new CommentItem
                                                                            {
                                                                                PostedBy = new UserItem
                                                                                            {
                                                                                                Name = c.aspnet_User.UserName
                                                                                            },
                                                                                PostedOn = c.PostedOn,
                                                                                Content = c.Content
                                                                            }
                                                                        ).ToArray(),

                                            Songs = Stories
                                                            .Where(v => v.Status != 0 &&
                                                                 (from story in Stories
                                                                  join artist in ARTISTs on story.ARTIST_IDZ equals artist.ARTIST_IDZ
                                                                  join artist_similar in ARTIST_SIMILARs on artist.ARTIST_IDZ equals artist_similar.ARTIST_ID
                                                                  where story.ID == s.ID
                                                                  select artist_similar.SIMILARARTIST_ID).Contains(v.ARTIST_IDZ)
                                                             )
                                                             .Union(from story in Stories
                                                                    where story.ARTIST_IDZ == s.ARTIST_IDZ
                                                                    && story.YouTubeID != null
                                                                    select story)
                                                            .OrderByDescending(v => v.Playcount)
                                                            .Select(v => new SongSmallBin
                                                                   {
                                                                       StoryID = v.ID,
                                                                       name = v.Title + " - " + v.ArtistName,
                                                                       MP3FileID = (int?)(v.MP3FILEs.FirstOrDefault().MP3_FILEIDZ) ?? 0,
                                                                       mp3 = (v.MP3FILEs.FirstOrDefault().url) ?? string.Empty,
                                                                       YouTubeID = v.YouTubeID
                                                                   })
                                                            .Take(100)
                                                            .Distinct()
                                                            .ToList(),
                                            //ArtistNews=new GSearch.GNewsResults[0],
                                            //ArtistBlog=new GSearch.GBlogResults[0]
                                            //ArtistNews = googleApi.GetNews(s.ARTIST.NAME),
                                            //ArtistBlog = googleApi.GetBlogs(s.ARTIST.NAME)
                                        }
                                    ).FirstOrDefault();
            return song;
        }

        public List<SongSmallBin> GetSongs(int storyId, int artistId)
        {
            var songs = Stories
                                                            .Where(v => v.Status != 0 &&
                                                                 (from story in Stories
                                                                  join artist in ARTISTs on story.ARTIST_IDZ equals artist.ARTIST_IDZ
                                                                  join artist_similar in ARTIST_SIMILARs on artist.ARTIST_IDZ equals artist_similar.ARTIST_ID
                                                                  where story.ID == storyId
                                                                  select artist_similar.SIMILARARTIST_ID).Contains(v.ARTIST_IDZ)
                                                             )
                                                             .Union(from story in Stories
                                                                    where story.ARTIST_IDZ == artistId
                                                                    && story.YouTubeID != null
                                                                    select story)
                                                            .OrderByDescending(v => v.Playcount)
                                                            .Select(v => new SongSmallBin
                                                                   {
                                                                       StoryID = v.ID,
                                                                       name = v.Title + " - " + v.ArtistName,
                                                                       MP3FileID = (int?)(v.MP3FILEs.FirstOrDefault().MP3_FILEIDZ) ?? 0,
                                                                       mp3 = (v.MP3FILEs.FirstOrDefault().url) ?? string.Empty,
                                                                       YouTubeID = v.YouTubeID
                                                                   })
                                                            .Take(100)
                                                            .ToList();
            return songs;
        }

        /// <summary>
        /// Gets the upcoming stories.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetUpcomingStories(Guid userId, int start, int max, out int total)
        {
            var stories = Stories.Where(s => s.PostedOn != null);
            total = totalLimit;


            return stories
                           .Select
                           (
                              s =>
                              new StoryListItem
                              {
                                  ID = s.ID,
                                  Title = s.Title.Trim() != string.Empty ? s.Title : "Unknown",
                                  Description = s.Description,
                                  ArtistName = s.ARTIST.NAME,
                                  Category = s.Category.Name,
                                  Tags = new string[0],
                                  ImageID = s.ARTIST.IMAGEs.First().IMAGE_IDZ,
                                  PostedBy = new UserItem
                                             {
                                                 Name = s.PostedByUserName
                                             },
                                  PostedOn = s.PostedOn,
                                  PublishedOn = s.PublishedOn,
                                  VoteCount = s.Votes.Count(),
                                  HasVoted = (s.Votes.Count(v => v.UserID == userId) > 0),
                                  CommentCount = s.Comments.Count(),
                                  YouTubeDescription = s.youTubeDescription
                              }
                           )
                           .OrderByDescending(s => s.ID)
                           .Skip(start)
                           .Take(max)
                           .ToArray();
        }


        /// <summary>
        /// Gets the stories posted by the specified user.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="postedByUserId">The posted by user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetStoriesPostedByUser(Guid userId, string name, int start, int max, out int total)
        {
            var stories = from s in Stories
                          join fts in UserSearch(name) on s.ID equals fts.ID
                          select s;

            total = totalLimit;
            //total = stories.Count();
            //total = GetTotal(start, total);
            return PrepareStories(
                                    stories,
                                    userId,
                                    start,
                                    max
                                );
        }

        /// <summary>
        /// Gets the stories posted by the specified user.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="postedByUserId">The posted by user id.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] GetStoriesPostedByUser(Guid userId, Guid postedByUserId, int start, int max, out int total)
        {
            var stories = Stories
                                .Where(s =>
                                        aspnet_Users
                                                    .Where(a => a.UserName == s.PostedByUserName)
                                                    .SingleOrDefault()
                                                    .UserId == postedByUserId);
            total = totalLimit;

            return PrepareStories(
                                    stories,
                                    userId,
                                    start,
                                    max
                                );
        }

        public StoryListItem[] SearchSong(Guid userId, string query, int start, int max, out int total)
        {
            IQueryable<Story> stories = null;

            query = query.ToLower();
            query = query.Replace(" ", "%");

            stories = from s in Stories
                      join fts in fnSearchSong(query) on s.ID equals fts.KEY
                      select s;


            total = stories.Count();

            return PrepareStories(
                                stories,
                                userId,
                                start,
                                max
                            );
        }

        /// <summary>
        /// Searches the stories.
        /// </summary>
        /// <param name="userId">The currently visiting user id.</param>
        /// <param name="query">The query.</param>
        /// <param name="start">The start.</param>
        /// <param name="max">The max.</param>
        /// <param name="total">The total.</param>
        /// <returns></returns>
        public StoryListItem[] SearchStories(Guid userId, string query, string searchType, int start, int max, out int total)
        {
            IQueryable<Story> stories = null;

            query = query.ToLower();
            query = query.Replace(" ", "%");


            total = stories.Count();

            return PrepareStories(
                                stories,
                                userId,
                                start,
                                max
                            );
        }

        /// <summary>
        /// Returns an array of StoryListItem[] stories for specified parametars start and max
        /// </summary>
        /// <param name="stories"></param>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private static StoryListItem[] PrepareStories(IQueryable<Story> stories, Guid userId, int start, int max)
        {
            var tempStories =  stories
                            .Select
                            (
                               s =>
                               new StoryListItem
                               {
                                   ID = s.ID,
                                   Title = s.Title.Trim() != string.Empty ? s.Title : "Unknown",
                                   Description = s.Description,
                                   ArtistName = s.ArtistName,
                                   Category = s.Category.Name,
                                   Tags = new string[0],
                                   ImageID = s.ARTIST.IMAGEs.First().IMAGE_IDZ,
                                   PostedBy = new UserItem
                                              {
                                                  Name = s.PostedByUserName
                                              },
                                   PostedOn = s.PostedOn,
                                   PublishedOn = s.PublishedOn,
                                   VoteCount = s.Votes.Count(),
                                   HasVoted = (s.Votes.Count(v => v.UserID == userId) > 0),
                                   CommentCount = s.Comments.Count(),
                                   YouTubeDescription = s.youTubeDescription,
                                   Playcount = s.Playcount,
                                   YouTubeID = s.YouTubeID,
                                   Mp3Files = s.MP3FILEs
                                                          .Select(v => new Mp3FileItem
                                                                  {
                                                                      Url = v.url,
                                                                      UrlHandler = "/Song/GetStreamMp3/" + v.MP3_FILEIDZ.ToString() + "/" + s.ID.ToString(),
                                                                      Mp3File_ID = v.MP3_FILEIDZ,
                                                                      Story_ID = v.Story_ID,
                                                                      Title = v.Title
                                                                  }
                                                                  )
                                       
                                                          .ToArray()
                               }
                            )

                            
                            .Skip(start)
                            .Take(max)
                            .ToArray();

            return tempStories.OrderByDescending(s => s.Playcount).ToArray();
        }



        /// <summary>
        /// Osiromaseno za brzina 
        /// </summary>
        /// <param name="stories"></param>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private static StoryListItem[] PrepareStoriesForMoods(IQueryable<Story> stories, Guid userId)
        {
            return stories
                            .Select
                            (
                               s =>
                               new StoryListItem
                               {
                                   ID = s.ID,
                                   ArtistName = s.ArtistName,
                                   Title = s.Title,
                                   Playcount = s.Playcount,
                                   YouTubeID = s.YouTubeID,
                                   ImageID = s.ARTIST.IMAGEs
                                                                 .Select(v => v.IMAGE_IDZ)
                                                                 .FirstOrDefault(),
                                   Mp3Files = s.MP3FILEs
                                                          .Select(v => new Mp3FileItem
                                                          {
                                                              Url = v.url,
                                                              UrlHandler = "/Song/GetStreamMp3/" + v.MP3_FILEIDZ.ToString() + "/" + s.ID.ToString(),
                                                              Mp3File_ID = v.MP3_FILEIDZ,
                                                              Story_ID = v.Story_ID,
                                                              Title = v.Title
                                                          }
                                                          )
                                                          .ToArray()
                               }
                            )
                            .OrderByDescending(s => s.Playcount)
                            .ToArray();
        }

        /// <summary>
        /// Osiromaseno za brzina 
        /// </summary>
        /// <param name="stories"></param>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private static StoryListItem[] PrepareStoriesForMoods(IQueryable<Story> stories, Guid userId,int take,int skip)
        {
            return stories
                            .Select
                            (
                               s =>
                               new StoryListItem
                               {
                                   ID = s.ID,
                                   ArtistName = s.ArtistName,
                                   Title = s.Title,
                                   Playcount = s.Playcount,
                                   YouTubeID = s.YouTubeID,
                                   ImageID = s.ARTIST.IMAGEs
                                                                 .Select(v => v.IMAGE_IDZ)
                                                                 .FirstOrDefault(),
                                   Mp3Files = s.MP3FILEs
                                                          .Select(v => new Mp3FileItem
                                                          {
                                                              Url = v.url,
                                                              UrlHandler = "/Song/GetStreamMp3/" + v.MP3_FILEIDZ.ToString() + "/" + s.ID.ToString(),
                                                              Mp3File_ID = v.MP3_FILEIDZ,
                                                              Story_ID = v.Story_ID,
                                                              Title = v.Title
                                                          }
                                                          )
                                                          .ToArray()
                               }
                            )
                            .Skip(skip)
                            .Take(take)
                            .ToArray();
        }

        /// <summary>
        /// Returns an array of StoryListItem[] stories for specified parametars start and max
        /// Ordered by the most votes
        /// </summary>
        /// <param name="stories"></param>
        /// <param name="userId"></param>
        /// <param name="start"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private static StoryListItem[] PrepareStoriesForTop10(IQueryable<Story> stories, Guid userId, int start, int max)
        {
            max = 10;
            if (start > 10000)
                start = 10000;
            var top10 = stories.
                            Select
                            (
                               s =>
                               new StoryListItem
                               {
                                   ID = s.ID,
                                   Title = s.Title,
                                   Description = s.Description,
                                   // added fields
                                   //ImageName = s.ImageName,
                                   ImageID = s.ARTIST.IMAGEs.First().IMAGE_IDZ,
                                   ArtistName = s.ArtistName,
                                   Category = s.Category.Name,
                                   //HasImage = (bool)s.HasImage,
                                   VoteCount = s.Votes.Count,
                                   PostedOn = s.PostedOn
                               }
                            )
                            .OrderByDescending(s => s.PostedOn)
                            .Skip(start)
                            .Take(max)
                            .OrderByDescending(s => s.VoteCount);
            return top10.ToArray();
        }

        /// <summary>
        /// Submit the story.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="title">The title.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="description">The description.</param>
        /// <param name="tags">The tags.</param>
        /// <param name="userId">The user id who is submitting the story.</param>
        /// <param name="ArtistName">Name of the company</param>
        /// <param name="startingDate">Starting date of the internship</param>
        /// <param name="Duration">Ending date of the internship</param>
        /// <param name="location">Location of the intersnhip</param>
        /// <param name="requirements">Requirements for the internship</param>
        /// <param name="languageRequirements">language Requirements</param>
        /// <param name="payment">Payment</param>
        /// <param name="contact">Contact</param>
        /// <param name="uploadPic">Upload Picture</param>
        /// <param name="uploadDoc">Upload document</param>
        /// <param name="additionalInfo">Additional Info</param>
        /// <param name="documentName">Document Name</param>
        /// <param name="imageName">Image Name</param>
        /// <returns>Returns the id of the new story</returns>

        public int SubmitStory(string songTitle, string artistName, int categoryId, string description, string tags, List<String> fileUrl, string videoID, Guid userId, string youTubeDescription)
        {
            using (var ts = new TransactionScope())
            {
                var category = Categories.FirstOrDefault(c => c.ID == categoryId);

                if (category == null)
                {
                    throw new InvalidOperationException("Specified category does not exist.");
                }

                // Create artist if it doesn't exist
                int artistID = CreateArtist(artistName, categoryId);

                var now = DateTime.UtcNow;

                var story = new Story
                                    {
                                        Title = WebHelper.CreateAmper(songTitle.Trim()),
                                        Description = description.Trim(),
                                        CategoryID = categoryId,
                                        //PostedBy = userId,
                                        PostedByUserName = aspnet_Users.Where(s => s.UserId == userId).SingleOrDefault().UserName,
                                        PostedOn = now,
                                        ARTIST_IDZ = artistID,
                                        ArtistName = WebHelper.CreateAmper(artistName.Trim()),
                                        YouTubeID = videoID.Trim(),
                                        youTubeDescription = youTubeDescription
                                    };

                Stories.InsertOnSubmit(story);

                SubmitChanges();

                #region mp3Files

                int counterMp3 = 1;

                foreach (string mp3Url in fileUrl)
                {
                    MP3FILE mp3FileObject = new MP3FILE
                    {
                        Story_ID = story.ID,
                        url = mp3Url,
                        IsValid = true,
                        Title = WebHelper.CreateAmper(songTitle + " - " + artistName),
                        DateCreated = DateTime.Now,
                        Count = counterMp3
                    };
                    MP3FILEs.InsertOnSubmit(mp3FileObject);
                    counterMp3++;
                }

                #endregion

                #region Tags

                if (!string.IsNullOrEmpty(tags))
                {
                    var tagsArray = tags.Split(',');

                    if (tagsArray.Length > 0)
                    {
                        var newTags = new List<Tag>();
                        var allTags = new List<Tag>();

                        for (var i = 0; i < tagsArray.Length; i++)
                        {
                            var tagName = tagsArray[i].Trim();

                            if (tagName.Length > 0)
                            {
                                if (tagName.Length > 64)
                                    tagName = tagName.Substring(0, 64);
                                var tag = Tags.FirstOrDefault(t => t.Name == tagName);

                                if (tag == null)
                                {
                                    tag = new Tag { Name = tagName };
                                    newTags.Add(tag);
                                }

                                allTags.Add(tag);
                            }
                        }

                        if (newTags.Count > 0)
                        {
                            Tags.InsertAllOnSubmit(newTags);
                            SubmitChanges();
                        }

                        if (allTags.Count > 0)
                        {
                            var storyTags = new List<StoryTag>();

                            for (var i = 0; i < allTags.Count; i++)
                            {
                                storyTags.Add(new StoryTag { StoryID = story.ID, TagID = allTags[i].ID });
                            }

                            StoryTags.InsertAllOnSubmit(storyTags);
                            SubmitChanges();
                        }
                    }
                }

                #endregion Tags

                #region Votes

                var vote = new Vote { StoryID = story.ID, UserID = userId, Timestamp = now };
                Votes.InsertOnSubmit(vote);

                #endregion Votes

                SubmitChanges();
                ts.Complete();
                return story.ID;
            }
        }

        /// <summary>
        /// The same as regular with 4 votes only
        /// </summary>
        /// <param name="songTitle"></param>
        /// <param name="artistName"></param>
        /// <param name="categoryId"></param>
        /// <param name="description"></param>
        /// <param name="tags"></param>
        /// <param name="fileUrl"></param>
        /// <param name="encodingCode"></param>
        /// <param name="videoID"></param>
        /// <param name="imageURL"></param>
        /// <param name="hasImage"></param>
        /// <param name="userId"></param>
        /// <param name="youTubeDescription"></param>
        /// <returns></returns>

        public int SubmitStoryBot(string songTitle, string artistName, int categoryId, string description, string tags, List<String> fileUrl, string videoID, Guid userId, string youTubeDescription)
        {
            using (var ts = new TransactionScope())
            {
                var category = Categories.FirstOrDefault(c => c.ID == categoryId);

                if (category == null)
                {
                    throw new InvalidOperationException("Specified category does not exist.");
                }

                // Create artist if it doesn't exist
                int artistID;
                artistName = artistName.Replace(".", "");
                if (GetArtistByName(artistName) != null)
                    artistID = GetArtistByName(artistName).ARTIST_IDZ;
                else
                    artistID = CreateArtist(artistName, categoryId);

                var now = DateTime.UtcNow;

                var story = new Story
                {
                    Title = WebHelper.CreateAmper(songTitle.Trim()),
                    Description = description.Trim(),
                    youTubeDescription = youTubeDescription.Trim(),
                    CategoryID = categoryId,
                    PostedByUserName = aspnet_Users.Where(s => s.UserId == userId).SingleOrDefault().UserName,
                    PostedOn = now,
                    ARTIST_IDZ = artistID,
                    ArtistName = WebHelper.CreateAmper(artistName.Trim()),
                    YouTubeID = videoID.Trim(),
                    Status = 1
                };

                Stories.InsertOnSubmit(story);

                SubmitChanges();

                #region mp3Files

                int counterMp3 = 1;

                foreach (string mp3Url in fileUrl)
                {
                    if (mp3Url.Length < 512)
                    {
                        MP3FILE mp3FileObject = new MP3FILE
                        {
                            Story_ID = story.ID,
                            url = mp3Url,
                            IsValid = true,
                            Title = WebHelper.CreateAmper(songTitle + " - " + artistName),
                            DateCreated = DateTime.Now,
                            Count = counterMp3
                        };
                        MP3FILEs.InsertOnSubmit(mp3FileObject);
                        counterMp3++;
                    }
                }

                #endregion

                #region Tags

                if (!string.IsNullOrEmpty(tags))
                {
                    var tagsArray = tags.Split(',');

                    if (tagsArray.Length > 0)
                    {
                        var newTags = new List<Tag>();
                        var allTags = new List<Tag>();

                        for (var i = 0; i < tagsArray.Length; i++)
                        {
                            var tagName = tagsArray[i].Trim();

                            if (tagName.Length > 0)
                            {
                                if (tagName.Length > 64)
                                    tagName = tagName.Substring(0, 64);
                                var tag = Tags.FirstOrDefault(t => t.Name == tagName);

                                if (tag == null)
                                {
                                    tag = new Tag { Name = tagName };
                                    newTags.Add(tag);
                                }

                                allTags.Add(tag);
                            }
                        }

                        if (newTags.Count > 0)
                        {
                            Tags.InsertAllOnSubmit(newTags);
                            SubmitChanges();
                        }

                        if (allTags.Count > 0)
                        {
                            var storyTags = new List<StoryTag>();

                            for (var i = 0; i < allTags.Count; i++)
                            {
                                storyTags.Add(new StoryTag { StoryID = story.ID, TagID = allTags[i].ID });
                            }

                            StoryTags.InsertAllOnSubmit(storyTags);
                            SubmitChanges();
                        }
                    }
                }

                #endregion Tags

                #region Votes

                var vote = new Vote { StoryID = story.ID, UserID = userId, Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("9E755425-EE28-47A3-A235-F8F3647C163A"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("09D8939E-A743-4D77-AD15-637E2F216164"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("7F95F2B3-BC65-40A8-A801-0ED9C5E770C7"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("D13D8B0C-321F-46DC-B825-C5FCA9BBABC8"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                vote = new Vote { StoryID = story.ID, UserID = new Guid("2EA629AC-DCEC-4F12-B953-DC274768D6ED"), Timestamp = now };
                Votes.InsertOnSubmit(vote);

                story.PublishedOn = DateTime.Now;
                #endregion Votes


                SubmitChanges();
                ts.Complete();
                return story.ID;
            }
        }

        public int SubmitStoryBotArtist(string songTitle, string artistName, int categoryId, string description, string tags, List<String> fileUrl, string encodingCode, string videoID, string imageURL, bool hasImage, Guid userId, string youTubeDescription)
        {
            using (var ts = new TransactionScope())
            {
                var category = Categories.FirstOrDefault(c => c.ID == categoryId);

                if (category == null)
                {
                    throw new InvalidOperationException("Specified category does not exist.");
                }

                // Create artist if it doesn't exist
                int artistID = GetArtistByName(artistName).ARTIST_IDZ;

                var now = DateTime.UtcNow;

                var story = new Story
                {
                    Title = WebHelper.CreateAmper(songTitle.Trim()),
                    Description = description.Trim(),
                    CategoryID = categoryId,
                    //PostedBy = userId,
                    PostedByUserName = aspnet_Users.Where(s => s.UserId == userId).SingleOrDefault().UserName,
                    PostedOn = now,
                    ARTIST_IDZ = artistID,
                    ArtistName = WebHelper.CreateAmper(artistName.Trim()),
                    YouTubeID = videoID.Trim(),
                    youTubeDescription = youTubeDescription
                };

                Stories.InsertOnSubmit(story);

                SubmitChanges();

                #region mp3Files

                int counterMp3 = 1;

                foreach (string mp3Url in fileUrl)
                {
                    if (mp3Url.Length < 512)
                    {
                        MP3FILE mp3FileObject = new MP3FILE
                        {
                            Story_ID = story.ID,
                            url = mp3Url,
                            IsValid = true,
                            Title = WebHelper.CreateAmper(songTitle + " - " + artistName),
                            DateCreated = DateTime.Now,
                            Count = counterMp3
                        };
                        MP3FILEs.InsertOnSubmit(mp3FileObject);
                        counterMp3++;
                    }
                }

                #endregion

                #region Tags

                if (!string.IsNullOrEmpty(tags))
                {
                    var tagsArray = tags.Split(',');

                    if (tagsArray.Length > 0)
                    {
                        var newTags = new List<Tag>();
                        var allTags = new List<Tag>();

                        for (var i = 0; i < tagsArray.Length; i++)
                        {
                            var tagName = tagsArray[i].Trim();

                            if (tagName.Length > 0)
                            {
                                if (tagName.Length > 64)
                                    tagName = tagName.Substring(0, 64);
                                var tag = Tags.FirstOrDefault(t => t.Name == tagName);

                                if (tag == null)
                                {
                                    tag = new Tag { Name = tagName };
                                    newTags.Add(tag);
                                }

                                allTags.Add(tag);
                            }
                        }

                        if (newTags.Count > 0)
                        {
                            Tags.InsertAllOnSubmit(newTags);
                            SubmitChanges();
                        }

                        if (allTags.Count > 0)
                        {
                            var storyTags = new List<StoryTag>();

                            for (var i = 0; i < allTags.Count; i++)
                            {
                                storyTags.Add(new StoryTag { StoryID = story.ID, TagID = allTags[i].ID });
                            }

                            StoryTags.InsertAllOnSubmit(storyTags);
                            SubmitChanges();
                        }
                    }
                }

                #endregion Tags

                #region Votes

                var vote = new Vote { StoryID = story.ID, UserID = userId, Timestamp = now };
                Votes.InsertOnSubmit(vote);

                story.PublishedOn = new DateTime(2009, 4, 7, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
                //story.PublishedOn = new DateTime(2009, 4, 7);

                #endregion Votes

                SubmitChanges();
                ts.Complete();
                return story.ID;
            }
        }

        public int SubmitStoryBotArtistPoor(string songTitle, string artistName, int artistID, int categoryId, string description, Guid userId, int? year)
        {
            using (var ts = new TransactionScope())
            {
                var category = Categories.FirstOrDefault(c => c.ID == categoryId);

                if (category == null)
                {
                    throw new InvalidOperationException("Specified category does not exist.");
                }

                var now = DateTime.UtcNow;

                var story = new Story
                {
                    ARTIST_IDZ = artistID,
                    Title = WebHelper.CreateAmper(songTitle.Trim()),
                    Year = year,
                    Description = description.Trim(),
                    CategoryID = categoryId,
                    PostedByUserName = aspnet_Users.Where(s => s.UserId == userId).SingleOrDefault().UserName,
                    PostedOn = now,
                    ArtistName = WebHelper.CreateAmper(artistName.Trim()),
                    youTubeDescription = description,
                    Status = 0
                };

                Stories.InsertOnSubmit(story);

                SubmitChanges();

                #region Votes

                var vote = new Vote { StoryID = story.ID, UserID = userId, Timestamp = now };
                Votes.InsertOnSubmit(vote);

                story.PublishedOn = new DateTime(2007, 3, 1, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
                story.PostedOn = new DateTime(2007, 3, 1, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);

                #endregion Votes

                SubmitChanges();
                ts.Complete();
                return story.ID;
            }
        }

        public bool StoryExists(string songName, string artistName)
        {
            List<Story> stories = Stories.Where(s => s.Title == songName && s.ArtistName == artistName).ToList();
            if (stories.Count == 0)
                return false;
            else
                return true;
        }

        private int CreateArtist(string artistName, int categoryId)
        {
            artistName = WebHelper.CreateAmper(artistName);
            int artistID;
            List<IMAGE> listaSliki = new List<IMAGE>();
            ARTIST artist = new ARTIST();

            artist = GetArtistByName(artistName);

            if (artist == null)
            {
                try
                {
                    using (var ts = new TransactionScope())
                    {
                        artist = new ARTIST();
                        artist.DateCreated = DateTime.Now;
                        artist.Category = categoryId;

                        #region Basic info

                        DISCOGZ disco = new DISCOGZ();
                        disco.API_KEY = "c09e193fa7";
                        DiscogsAPI.ResponseClasses.ArtistRequest.artist art = disco.FindArtist(artistName);
                        int counter = 0;

                        if (art != null)
                        {
                            artist.NAME = WebHelper.CutString(art.name, 149);

                            if (art.aliases != null)
                            {
                                foreach (string alias in art.aliases)
                                {
                                    artist.aliases = artist.aliases + "|" + alias;
                                    counter++;
                                    if (counter > 15)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.aliases = WebHelper.CutString(artist.aliases, 3999);
                            }

                            if (art.namevariations != null)
                            {
                                foreach (string nameVar in art.namevariations)
                                {
                                    artist.namevariations = artist.namevariations + "|" + nameVar;
                                    counter++;
                                    if (counter > 10)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.namevariations = WebHelper.CutString(artist.namevariations, 3999);
                            }

                            artist.REALNAME = WebHelper.CutString(art.realname, 100);

                            if (art.urls != null)
                            {
                                foreach (string uri in art.urls)
                                {
                                    artist.URLS = artist.URLS + "|" + uri;
                                    counter++;
                                    if (counter > 10)
                                    {
                                        counter = 0;
                                        break;
                                    }
                                }
                                artist.URLS = WebHelper.CutString(artist.URLS, 3999);
                            }
                        }
                        else
                        {// Create the artist if it doesn't exist in the api
                            artist.NAME = WebHelper.CutString(artistName, 149);
                        }

                        artist.DateCreated = DateTime.Now;

                        #endregion Basic Info

                        ARTISTs.InsertOnSubmit(artist);
                        SubmitChanges();
                        artistID = artist.ARTIST_IDZ;

                        #region Images

                        listaSliki = disco.GetImages(artist.NAME, artist.ARTIST_IDZ);
                        if (listaSliki.Count == 0)
                        {
                            GoogleAPI googleAPI = new GoogleAPI();
                            listaSliki = googleAPI.GetImages(artist.NAME, artist.ARTIST_IDZ);
                        }

                        IMAGEs.InsertAllOnSubmit(listaSliki);
                        SubmitChanges();

                        #endregion Images

                        #region AllMusic

                        AllMusicBin allMusicBin = AllMusicAPI.SearchRequest(artist.NAME);
                        if (allMusicBin == null)
                            SetArtistProbablyNotValidFlag(artist);
                        else
                            InsertAllMusicBin(ref allMusicBin, ref artist);

                        SubmitChanges();

                        #endregion

                        #region EchoNest

                        EchoArtistBin echoBin = EchonestAPI.SearchRequest(artist.NAME);

                        if (echoBin == null)
                            EchoNotValid(artist);
                        else
                            InsertEchoBin(ref echoBin, ref artist);

                        #endregion

                        SubmitChanges();
                        ts.Complete();
                    }
                }
                catch (Exception ex)
                {
                    throw new ApplicationException(ex.Message);
                }
            }
            else
                artistID = artist.ARTIST_IDZ;
            return artistID;
        }

        /// <summary>
        /// Method should add all other songs for this artist
        /// </summary>
        /// <param name="art"></param>
        private void InsertOtherStories(DiscogsAPI.ResponseClasses.ArtistRequest.artist art)
        {


        }
        /// <summary>
        /// Returns the specific story for the specified id
        /// </summary>
        /// <param name="storyId">The id of the story</param>
        /// <returns></returns>
        public Story GetStoryById(int storyId)
        {
            Story story = (from c in Stories
                           where c.ID == storyId
                           select c).FirstOrDefault();

            if (story == null)
                throw new ApplicationException(String.Format("Can't find an Entry with the StoryID ={0}", storyId));
            return story;
        }

        public void LoveStory(int storyId, Guid userId, int qualifyingLove)
        {
            using (var ts = new TransactionScope())
            {
                var story = Stories.FirstOrDefault(s => s.ID == storyId);

                if (story == null)
                {
                    throw new InvalidOperationException("Specified story does not exist.");
                }

                var vote = Votes.FirstOrDefault(v => v.StoryID == storyId && v.UserID == userId);

                if (vote == null)
                {
                    var voteCount = Votes.Where(v => v.StoryID == storyId).Count();
                    var now = DateTime.UtcNow;

                    if ((voteCount + 1) == qualifyingLove)
                    {
                        story.PublishedOn = now;
                    }

                    vote = new Vote { StoryID = storyId, UserID = userId, Timestamp = now };

                    Votes.InsertOnSubmit(vote);
                    SubmitChanges();
                    ts.Complete();
                }
            }
        }

        /// <summary>
        /// Post comments for the specified story.
        /// </summary>
        /// <param name="storyId">The story id.</param>
        /// <param name="userId">The user id who is posting the comment.</param>
        /// <param name="content">The content.</param>
        /// <returns>Returns the id of the new comment</returns>
        public int PostComment(int storyId, Guid userId, string content)
        {
            using (var ts = new TransactionScope())
            {
                var story = Stories.FirstOrDefault(s => s.ID == storyId);

                if (story == null)
                {
                    throw new InvalidOperationException("Specified story does not exist.");
                }

                var comment = new Comment
                {
                    StoryID = storyId,
                    Content = content.Trim(),
                    PostedBy = userId,
                    PostedOn = DateTime.UtcNow
                };

                Comments.InsertOnSubmit(comment);
                SubmitChanges();

                ts.Complete();

                return comment.ID;
            }
        }

        public List<CloudHolder> AllMoods()
        {
            Random r=new Random();
            int randBroj = r.Next(10,2000);
            var moods = fnGetMoods()
                .Where(s=>s.co>randBroj)
                                    .Select(s => new CloudHolder
                                    {
                                        mood = s.value.Replace("/", ""),
                                        counter = s.co * 10
                                    })
                                    
                                    .Take(100)
                                    .ToList();

            return moods.ToList();
        }

        #endregion Story

        #region DeleteStory

        /// <summary>
        /// Deletes all tags for the specified story
        /// </summary>
        /// <param name="storyId">The id of the story</param>
        private void DeleteTagForStory(int storyId)// deletes the tag for the storyid so no foreign key problems
        {
            StoryTag storyTag = (from c in StoryTags
                                 where c.StoryID == storyId
                                 select c).FirstOrDefault();
            while (storyTag != null)
            {
                StoryTags.DeleteOnSubmit(storyTag);
                SubmitChanges();
                storyTag = (from c in StoryTags
                            where c.StoryID == storyId
                            select c).FirstOrDefault();
            }
        }
        /// <summary>
        /// Deletes all votes for the specified story 
        /// </summary>
        /// <param name="storyId">The id of the story</param>
        private void DeleteVoteForStory(int storyId) // deletes the vote so no foreign key problems
        {

            Vote vote = (from c in Votes
                         where c.StoryID == storyId
                         select c).FirstOrDefault();
            while (vote != null)
            {
                Votes.DeleteOnSubmit(vote);
                SubmitChanges();
                vote = (from c in Votes
                        where c.StoryID == storyId
                        select c).FirstOrDefault();
            }
        }
        /// <summary>
        /// Deletes all Comments for the specified story
        /// </summary>
        /// <param name="storyId">The id of the story</param>

        private void DeleteCommentForStory(int storyId)
        {
            Comment comment = (from c in Comments
                               where c.StoryID == storyId
                               select c).FirstOrDefault();

            while (comment != null)
            {
                Comments.DeleteOnSubmit(comment);
                SubmitChanges();
                comment = (from c in Comments
                           where c.StoryID == storyId
                           select c).FirstOrDefault();
            }
        }

        public void DeleteMp3(MP3FILE mp3File)
        {
            MP3FILEs.DeleteOnSubmit(mp3File);
            // Commented out on purpose for the changes to take efeect on request SPPEED :)
            //SubmitChanges();
        }

        public void DeleteStory(int storyId)
        {
            try
            {
                DeleteCommentForStory(storyId);
                DeleteTagForStory(storyId);
                DeleteVoteForStory(storyId);
                foreach (MP3FILE mp3 in MP3FILEs.Where(s => s.Story_ID == storyId).ToList())
                {
                    MP3FILEs.DeleteOnSubmit(mp3);
                }
                Story str = GetStoryById(storyId);
                Stories.DeleteOnSubmit(str);
                SubmitChanges();
            }
            catch (Exception e)
            {
                throw new ApplicationException(e.ToString());
            }

        }
        /// <summary>
        /// Loves the specified story.
        /// </summary>
        /// <param name="storyId">The story id.</param>
        /// <param name="userId">The user id who is loving the story.</param>
        /// <param name="qualifyingLove">The qualifying love which is considered to mark a story as published.</param>

        #endregion DeleteStory

        #region ARTIST

        public List<CloudHolder> Get50Artist()
        {
            Random r = new Random();
            int randBroj = r.Next(0, 30000);
            var art = ARTISTs
                        .Where(s => s.ARTIST_IDZ > randBroj && s.hotttnesss > 0 && s.hotttnesss < 1
                        && s.Stories.Count > 0 && s.status != 0 && s.Stories.FirstOrDefault().MP3FILEs.Count > 0)

                        .Select(s => new CloudHolder
                        {
                            id = s.ARTIST_IDZ,
                            mood = s.NAME,
                            counter = (int?)(s.hotttnesss * 100000)
                        })
                        .Take(50)
                        .ToList();
            return art;
        }

        public ARTIST GetArtistByName(string artistName)
        {
            try
            {
                return ARTISTs.SingleOrDefault(s => s.NAME == artistName);
            }
            catch
            {
                return null;
            }
        }

        public IEnumerable<ARTIST> GetAllArtists()
        {
            return ARTISTs;
        }

        public IEnumerable<ARTIST> GetAllArtistsThanUrlContains(string str)
        {
            return ARTISTs.Where(s => s.IMAGEs.First().URL.Contains(str));
        }

        public IEnumerable<ARTIST> GetAllArtistsThatAreNotUpdated()
        {
            return ARTISTs.Where(s => s.status != null && s.status != -1 && s.status != 3 && s.status != 2 && s.status != 667).Take(10);
        }

        /// <summary>
        /// Grab all music bin data and insert it in database.
        /// INSERT ARTIST IN DB
        /// </summary>
        /// <param name="allMusicBin"></param>
        public void InsertAllMusicBin(ref AllMusicBin allMusicBin, ref ARTIST artist)
        {
            try
            {
                List<ARTIST_LIST> artistList = new List<ARTIST_LIST>();
                if (artist == null)
                    return;
                int counter = 1;

                #region artist

                artist.Category = allMusicBin.Category;
                artist.MiniBio = allMusicBin.MiniBio;
                artist.Born = allMusicBin.Born;
                artist.Died = allMusicBin.Died;
                artist.status = 1;

                #endregion

                #region styles

                counter = 1;
                foreach (string style in allMusicBin.Styles)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "style",
                        Value = style,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion styles

                #region moods

                counter = 1;
                foreach (string moods in allMusicBin.Moods)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "moods",
                        Value = moods,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion moods

                #region similar artists

                counter = 1;
                foreach (string similarArtists in allMusicBin.SimilarArtists)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "similarArtists",
                        Value = similarArtists,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion

                #region years active

                counter = 1;
                foreach (string yearsActive in allMusicBin.YearsActive)
                {
                    ARTIST_LIST artist_List = new ARTIST_LIST()
                    {
                        ARTIST_IDZ = artist.ARTIST_IDZ,
                        Type = "yearsActive",
                        Value = yearsActive,
                        counter = counter++
                    };
                    ARTIST_LISTs.InsertOnSubmit(artist_List);
                }

                #endregion

                artist.status = 1;
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "AllMusic Inserting artist=" + artist.NAME);
            }
        }

        public void SetArtistProbablyNotValidFlag(ARTIST artist)
        {
            using (var ts = new TransactionScope())
            {
                if (artist == null)
                {
                    ts.Dispose();
                    throw new ApplicationException("ARTIST IS NULL");
                }
                artist.status = -1;
                SubmitChanges();
                ts.Complete();
            }
        }

        /// <summary>
        /// Get's all artist information and sends it to ArtistController
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="artistName"></param>
        /// <returns></returns>
        public ArtistDetailItem GetArtistDetailByName(Guid userId, string artistName)
        {
            var artist = ARTISTs.Where(s => s.NAME == artistName)
                            .Select(s =>
                                        new ArtistDetailItem
                                        {
                                            Name = s.NAME,
                                            RealName = s.REALNAME,
                                            NameVariationsFromDatabase = s.namevariations ?? string.Empty,
                                            Aliases = WebHelper.SplitString(s.aliases.Substring(1, s.aliases.Length - 1), "|"),
                                            Urls = WebHelper.SplitString(s.URLS.Substring(1, s.URLS.Length - 1), "|"),
                                            ID = s.ARTIST_IDZ,
                                            Category = s.Category1.Name,
                                            DateCreated = s.DateCreated,
                                            Born = s.Born,
                                            Died = s.Died,
                                            MiniBio = s.MiniBio,
                                            status = s.status,
                                            EchoID = s.EchoID,
                                            Familiarity = s.Familiarity,
                                            Hotness = s.hotttnesss,

                                            Styles = s.ARTIST_LISTs
                                                                 .Where(v => v.Type == "style")
                                                                 .Select(v => v.Value)
                                                                 .ToList(),

                                            Moods = s.ARTIST_LISTs
                                                                 .Where(v => v.Type == "moods")
                                                                 .Select(v => v.Value)
                                                                 .ToList(),

                                            SimilarArtists = s.ARTIST_LISTs
                                                                 .Where(v => v.Type == "similarArtists")
                                                                 .Select(v => v.Value.Replace(" ", "+"))
                                                                 .ToList(),
                                            Images = s.IMAGEs
                                                                 .Select(v => v.IMAGE_IDZ)
                                                                 .ToList(),
                                            Bios = s.ARTIST_BIOs
                                                                 .Select(v =>
                                                                        new Bio
                                                                        {
                                                                            SiteName = v.SiteName,
                                                                            SourceUrl = v.SourceUrl,
                                                                            Text = v.Text
                                                                        })
                                                                        .ToList(),
                                            Blogs = s.ARTIST_BLOGs
                                                                 .Select(v =>
                                                                        new Blog
                                                                        {
                                                                            Name = v.Name,
                                                                            Summary = v.Summary,
                                                                            Url = v.Url
                                                                        })
                                                                        .ToList(),

                                            Reviews = s.ARTIST_REVIEWs
                                                               .Select(v =>
                                                                      new Review
                                                                      {
                                                                          ImageUrl = v.ImageURL,
                                                                          Name = v.Name,
                                                                          ReleaseName = v.ReleaseName,
                                                                          Summary = v.Summary,
                                                                          Url = v.URL
                                                                      })
                                                                      .ToList(),
                                            Songs = s.Stories
                                                               .Where(z => z.MP3FILEs.Count() > 0)
                                                               .Select(group =>
                                                                     new SongSmallBin
                                                                     {
                                                                         StoryID = group.ID,
                                                                         name = group.Title,
                                                                         Title = group.Title,
                                                                         url = group.MP3FILEs.FirstOrDefault().url,
                                                                         MP3FileID = (int?)(group.MP3FILEs.FirstOrDefault().MP3_FILEIDZ) ?? 0,
                                                                         YouTubeID = group.YouTubeID ?? string.Empty,
                                                                         Playcount = group.Playcount
                                                                     })
                                                                     .OrderByDescending(va => va.Playcount)
                                                              .ToList()
                                        }
                                    );

            return artist.FirstOrDefault();
        }

        public void EchoNotValid(ARTIST artist)
        {
            artist.EchoStatus = -1;
            SubmitChanges();
        }

        /// <summary>
        /// Echo bin artist data inserting
        /// </summary>
        /// <param name="echoBin"></param>
        /// <param name="artist"></param>
        public void InsertEchoBin(ref EchoArtistBin echoBin, ref ARTIST artist)
        {
            try
            {

                if (artist == null)
                    return;

                #region Artist

                artist.EchoID = echoBin.EchoID;
                artist.Familiarity = echoBin.familiarity;
                artist.hotttnesss = echoBin.hotttnesss;

                #endregion

                #region Bio

                if (echoBin.Biographies != null)
                {
                    foreach (Bio bio in echoBin.Biographies)
                    {
                        ARTIST_BIO artBio = new ARTIST_BIO()
                        {
                            ARTIST_IDZ = artist.ARTIST_IDZ,
                            SiteName = WebHelper.CutString(bio.SiteName, 128),
                            SourceUrl = WebHelper.CutString(bio.SourceUrl, 128),
                            Text = WebHelper.CutString(bio.Text, 3999)
                        };
                        ARTIST_BIOs.InsertOnSubmit(artBio);
                    }
                    SubmitChanges();
                }


                #endregion

                #region Blogs

                if (echoBin.Blogs != null)
                {
                    foreach (Blog blog in echoBin.Blogs)
                    {
                        ARTIST_BLOG artBlog = new ARTIST_BLOG();
                        artBlog.ARTIST_IDZ = artist.ARTIST_IDZ;
                        artBlog.Name = WebHelper.CutString(blog.Name, 128);
                        artBlog.Summary = WebHelper.CutString(blog.Summary, 3999);
                        artBlog.Url = WebHelper.CutString(blog.Url, 128);
                        ARTIST_BLOGs.InsertOnSubmit(artBlog);
                    }
                    SubmitChanges();
                }

                #endregion

                #region Reviews

                if (echoBin.Reviews != null)
                {
                    foreach (Review review in echoBin.Reviews)
                    {
                        ARTIST_REVIEW artReview = new ARTIST_REVIEW();
                        artReview.ARTIST_IDZ = artist.ARTIST_IDZ;
                        artReview.Name = WebHelper.CutString(review.Name, 128);
                        artReview.Summary = WebHelper.CutString(review.Summary, 3999);
                        artReview.URL = WebHelper.CutString(review.Url, 128);
                        artReview.ReleaseName = WebHelper.CutString(review.ReleaseName, 128);
                        artReview.ImageURL = WebHelper.CutString(review.ImageUrl, 128);
                        ARTIST_REVIEWs.InsertOnSubmit(artReview);
                    }
                    SubmitChanges();
                }

                #endregion

                artist.EchoStatus = 1;
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "Bakldflaskdjf");
            }
        }

        public ArtistDetailItem CreateArtistFromSimilar(Guid userID, string artistName)
        {
            artistName = WebHelper.CreateAmper(artistName);

            List<IMAGE> listaSliki = new List<IMAGE>();
            ARTIST artist = new ARTIST();
            artist.DateCreated = DateTime.Now;
            artist.Category = 15;
            try
            {
                using (var ts = new TransactionScope())
                {
                    #region Basic info

                    DISCOGZ disco = new DISCOGZ();
                    disco.API_KEY = "c09e193fa7";
                    DiscogsAPI.ResponseClasses.ArtistRequest.artist art = disco.FindArtist(artistName);
                    int counter = 0;
                    if (art != null)
                    {
                        artist.NAME = WebHelper.CutString(art.name, 149);

                        if (art.aliases != null)
                        {
                            foreach (string alias in art.aliases)
                            {
                                artist.aliases = artist.aliases + "|" + alias;
                                counter++;
                                if (counter > 15)
                                {
                                    counter = 0;
                                    break;
                                }
                            }
                            artist.aliases = WebHelper.CutString(artist.aliases, 3999);
                        }

                        if (art.namevariations != null)
                        {
                            foreach (string nameVar in art.namevariations)
                            {
                                artist.namevariations = artist.namevariations + "|" + nameVar;
                                counter++;
                                if (counter > 10)
                                {
                                    counter = 0;
                                    break;
                                }
                            }
                            artist.namevariations = WebHelper.CutString(artist.namevariations, 3999);
                        }

                        artist.REALNAME = WebHelper.CutString(art.realname, 100);

                        if (art.urls != null)
                        {
                            foreach (string uri in art.urls)
                            {
                                artist.URLS = artist.URLS + "|" + uri;
                                counter++;
                                if (counter > 10)
                                {
                                    counter = 0;
                                    break;
                                }
                            }
                            artist.URLS = WebHelper.CutString(artist.URLS, 3999);
                        }
                    }
                    else
                    {// Create the artist if it doesn't exist in the api
                        artist.NAME = WebHelper.CutString(artistName, 149);
                    }

                    artist.DateCreated = DateTime.Now;

                    #endregion Basic Info

                    ARTISTs.InsertOnSubmit(artist);
                    SubmitChanges();

                    #region Images

                    listaSliki = disco.GetImages(artist.NAME, artist.ARTIST_IDZ);
                    if (listaSliki.Count == 0)
                    {
                        GoogleAPI googleAPI = new GoogleAPI();
                        listaSliki = googleAPI.GetImages(artist.NAME, artist.ARTIST_IDZ);
                    }

                    IMAGEs.InsertAllOnSubmit(listaSliki);

                    #endregion Images

                    #region AllMusic

                    AllMusicBin allMusicBin = AllMusicAPI.SearchRequest(artist.NAME);

                    if (allMusicBin == null)
                    {
                        SetArtistProbablyNotValidFlag(artist);
                        artist.Category = 15;
                    }
                    else
                    {
                        InsertAllMusicBin(ref allMusicBin, ref artist);
                        artist.Category = allMusicBin.Category;
                    }

                    #endregion

                    #region EchoNest

                    EchoArtistBin echoBin = EchonestAPI.SearchRequest(artist.NAME);

                    if (echoBin == null)
                        EchoNotValid(artist);
                    else
                        InsertEchoBin(ref echoBin, ref artist);

                    #endregion

                    SubmitChanges();
                    ts.Complete();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return GetArtistDetailByName(userID, artist.NAME);
        }

        public ARTIST GetOneArtistNotUpdated()
        {
            foreach (ARTIST art in GetAllArtistsThatAreNotUpdated())
            {
                return art;
            }
            return null;
        }

        #endregion ARTIST

        #region Playlist

        private IEnumerable<YouTubeBin> GetYouTubePublishedPlaylist(Story story)
        {
            return Stories
                        .Where(s => s.Category == story.Category && s.PublishedOn != null && s.ID != story.ID && story.ID > s.ID && s.YouTubeID != string.Empty)
                        .OrderByDescending(s => s.PublishedOn)
                        .Select(s =>
                            new YouTubeBin
                            {
                                ID = s.ID,
                                YouTubeID = s.YouTubeID,
                            });
        }

        private IEnumerable<YouTubeBin> GetYouTubeUpcomingPlaylist(Story story)
        {
            return Stories
                        .Where(s => s.Category == story.Category && s.PublishedOn == null && s.ID != story.ID && story.ID > s.ID && s.YouTubeID != string.Empty)
                        .OrderByDescending(s => s.PostedOn)
                        .Select(s =>
                            new YouTubeBin
                            {
                                ID = s.ID,
                                YouTubeID = s.YouTubeID,
                            });
        }

        private IEnumerable<SongBin> Get100PublishedStories(Story story)
        {
            return Stories
                        .Where(s => s.Category == story.Category && s.PublishedOn != null && s.ID != story.ID && story.ID > s.ID && s.MP3FILEs.Count > 0)
                        .OrderByDescending(s => s.PublishedOn)
                        .Select(s =>
                            new SongBin
                            {
                                ID = s.ID,
                                PublishedOn = s.PublishedOn,
                                category = s.Category,
                                Mp3FileID = s.MP3FILEs.Where(v => v.IsValid == true).OrderBy(v => v.Count).FirstOrDefault().MP3_FILEIDZ,
                                Title = s.MP3FILEs.Where(v => v.IsValid == true).OrderBy(v => v.Count).FirstOrDefault().Title
                            })
                         ;
        }

        private IEnumerable<SongBin> Get100UpcomingStories(Story story)
        {
            return Stories
                        .Where(s => s.Category == story.Category && s.PublishedOn != null && s.ID != story.ID && story.ID > s.ID && s.MP3FILEs.Count > 0)
                        .Select(s =>
                            new SongBin
                            {
                                ID = s.ID,
                                PublishedOn = s.PublishedOn,
                                category = s.Category,
                                PostedOn = s.PostedOn,
                                Mp3FileID = s.MP3FILEs.Where(v => v.IsValid == true).OrderBy(v => v.Count).First().MP3_FILEIDZ,
                                Title = s.MP3FILEs.Where(v => v.IsValid == true).OrderBy(v => v.Count).First().Title
                            })
                         .OrderByDescending(v => v.PostedOn);
        }

        /// <summary>
        /// Get songs and titles for mp3 songs.
        /// </summary>
        /// <param name="story"></param>
        /// <returns></returns>
        private Mp3SongBin GetMp3List(Story story)
        {
            //Example url= /Song/GetStreamMp3/1D4CBDB1-196B-46B3-BFAA-13EB1E10FC73/602|/Song/GetStreamMp3/6C294415-F085-4E04-9DBE-76D238FD15B3/602|/Song/GetStreamMp3/FE648408-EAFB-4E7B-B77A-2DB19B21D88E/602|/Song/GetStreamMp3/9256AA61-1FA8-43EC-8990-B7EAF6D2F2D6/602|/Song/GetStreamMp3/51C13164-9BA2-4160-9D34-FB46ACC53822/602|/Song/GetStreamMp3/540D8CDF-D1CD-4D76-80C3-448665904FA9/602|/Song/GetStreamMp3/F6D66EEB-8A4E-427F-B3D3-7EC551579013/602|/Song/GetStreamMp3/B8E0F813-9DE7-481B-8FCD-B00740C83509/602|/Song/GetStreamMp3/01D31F0D-4DB4-40CD-A8FC-2ECC24AE8212/602|/Song/GetStreamMp3/8347F128-D851-40F8-85C1-737896581244/602|/Song/GetStreamMp3/BA118CC1-A2D9-4003-B1C9-7394AC29AEA9/602|/Song/GetStreamMp3/F8B7C51E-3605-48DC-BCE7-7621536D3B46/602|/Song/GetStreamMp3/D9C8EED2-A911-4737-B1E4-5AA32DF984F2/602|/Song/GetStreamMp3/FA6D0CC2-EE67-4398-8B05-4EC126EC4B1E/602|/Song/GetStreamMp3/4F604FAC-EE39-482F-90F6-BDA81A1621FC/602|/Song/GetStreamMp3/AF9B32AC-5FB0-4B8B-96F5-4E93E4010C0F/602|/Song/GetStreamMp3/42A930B9-B9CE-4DB7-A466-DB6A9F57E3F2/602|/Song/GetStreamMp3/31C74193-807A-4517-94A0-9AEFC94146DF/602|/Song/GetStreamMp3/77F5A2E2-D835-402A-ADCD-7C15E0FB09D8/602|/Song/GetStreamMp3/FEBC39C8-5E3A-41E9-9D27-548B01A56F6C/602|/Song/GetStreamMp3/FADD2829-C02A-434D-8447-76283CF2445B/602|/Song/GetStreamMp3/BF82E9CA-42B7-4516-B9B0-162FE9B925C9/602|/Song/GetStreamMp3/97C1EE0D-B636-46F7-B3F6-DFAE666323C0/602|/Song/GetStreamMp3/D176AAEB-480D-4A67-A5FA-11372CF4552C/602|/Song/GetStreamMp3/38FB73BE-4CAC-4027-9FC1-15EC522CDC7D/602&title=Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz|Pjanoo - Eric Prydz
            string playList = string.Empty;
            string titles = string.Empty;
            int counter = 0;
            bool hasFirstSong = false;
            Mp3SongBin pl = new Mp3SongBin();
            pl.Url = string.Empty;
            pl.Title = string.Empty;

            try
            {
                #region Get First Song

                if (story.MP3FILEs.Count != 0)
                {
                    var mp3 = story
                                        .MP3FILEs
                                        .Where(s => s.IsValid = true)
                                        .OrderBy(s => s.Count)
                                        .First();
                    playList = "/Song/GetStreamMp3/" + mp3.MP3_FILEIDZ.ToString() + "/" + story.ID.ToString();
                    titles = WebHelper.RemoveSpecialCharacters(mp3.Title);
                    hasFirstSong = true;
                }

                #endregion

                if (story.PublishedOn == null)
                {
                    #region Upcoming
                    foreach (Story sto in Stories.Where(s => s.Category == story.Category && s.PublishedOn == null && s.ID != story.ID && story.ID > s.ID).OrderByDescending(v => v.PostedOn).ToList())
                    {
                        if (sto.MP3FILEs.Count != 0)
                        {
                            var mp3 = sto
                                         .MP3FILEs
                                         .Where(s => s.IsValid = true)
                                         .OrderBy(s => s.Count)
                                         .First();

                            playList = playList + "|" + "/Song/GetStreamMp3/" + mp3.MP3_FILEIDZ.ToString() + "/" + story.ID.ToString();
                            titles = titles + "|" + mp3.Title;
                            if (++counter == 100)
                                break;
                        }
                    }
                    #endregion
                }
                else
                {
                    #region Published
                    foreach (SongBin songBin in Get100PublishedStories(story))
                    {
                        if (songBin.Mp3FileID != null && songBin.Mp3FileID != 0)
                        {
                            if (hasFirstSong == false)
                            {// Get First song 
                                playList = "/Song/GetStreamMp3/" + songBin.Mp3FileID.ToString() + "/" + songBin.ID.ToString();
                                titles = WebHelper.RemoveSpecialCharacters(songBin.Title);
                                hasFirstSong = true;
                            }
                            else
                            {
                                playList = playList + "|" + "/Song/GetStreamMp3/" + songBin.Mp3FileID.ToString() + "/" + songBin.ID.ToString();
                                titles = titles + "|" + WebHelper.RemoveSpecialCharacters(songBin.Title);
                                if (++counter == 100)
                                    break;

                            }
                        }

                    }

                    #endregion
                }
                pl.Url = playList;
                pl.Title = titles;
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "GetPlaylistMp3FormatedString()");
            }

            return pl;
        }

        /// <summary>
        ///  Get youtube playlist depending on category
        /// </summary>
        /// <param name="story"></param>
        /// <returns></returns>
        private List<string> GetYouTubePlayList(Story story)
        {
            int counter = 0;
            List<string> playList = new List<string>();

            #region First Song

            if (story.YouTubeID != null && story.YouTubeID != string.Empty)
                playList.Add(story.YouTubeID);

            #endregion

            if (story.PublishedOn == null)
            {// Upcoming
                foreach (Story sto in Stories.Where(s => s.Category == story.Category && s.PublishedOn == null && s.ID != story.ID && story.ID > s.ID).OrderByDescending(v => v.PostedOn).ToList())
                {
                    playList.Add(sto.YouTubeID);
                    if (++counter == 100)
                        break;
                }
            }
            else
            {// Published
                foreach (YouTubeBin youTubeBin in GetYouTubePublishedPlaylist(story))
                {
                    playList.Add(youTubeBin.YouTubeID);
                    if (++counter == 100)
                        break;
                }
            }
            return playList;
        }

        /// <summary>
        /// Get songs and titles for mp3 songs, for artist
        /// </summary>
        /// <param name="story"></param>
        /// <returns></returns>
        private Mp3SongBin GetMp3ListForArtist(IEnumerable<Story> stories)
        {
            int counter = 0;
            Mp3SongBin mp3Songs = new Mp3SongBin();
            mp3Songs.Url = string.Empty;
            mp3Songs.Title = string.Empty;
            try
            {
                MP3FILE mp3File;
                foreach (Story sto in stories)
                {
                    if (sto.MP3FILEs.Count != 0)
                    {
                        mp3File = sto
                                     .MP3FILEs
                                     .Where(s => s.IsValid = true)
                                     .OrderBy(s => s.Count)
                                     .First();

                        mp3Songs.Url = mp3Songs.Url + "|" + "/Song/GetStreamMp3/" + mp3File.MP3_FILEIDZ.ToString() + "/" + sto.ID.ToString();
                        mp3Songs.Title = mp3Songs.Title + "|" + mp3File.Title;
                        if (++counter == 99)
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                TraceLog.TimeWrite(ex, "GetPlaylistMp3FormatedString()");
            }

            return mp3Songs;
        }

        /// <summary>
        ///  Get youtube playlist depending on artistName
        /// </summary>
        /// <param name="story"></param>
        /// <returns></returns>
        private List<string> GetYoutubePlayListForArtist(IEnumerable<Story> stories)
        {
            int counter = 0;
            List<string> playList = new List<string>();
            foreach (Story sto in stories)
            {
                playList.Add(sto.YouTubeID);
                if (++counter == 100)
                    break;
            }

            return playList;
        }



        #endregion Playlist

        #region mp3

        public MP3FILE GetMp3UrlByID(int ID)
        {
            return MP3FILEs.Where(s => s.MP3_FILEIDZ == ID).SingleOrDefault();
        }

        /// <summary>
        /// Returns all mp3 files for the story
        /// </summary>
        /// <param name="storyID"></param>
        /// <returns></returns>
        public List<MP3FILE> Getallmp3(int storyID)
        {
            return MP3FILEs.Where(s => s.Story_ID == storyID).ToList();
        }


        #endregion

        #region sitemap

        //        <url>
        //  <loc>http://www.ilovethismusic.com/Song/Detail/414</loc>
        //  <changefreq>daily</changefreq>

        //  <priority>0.64</priority>
        //</url>
        private IEnumerable<Story> Get10Stories()
        {
            Random random = new Random();
            int num = random.Next(500000, 1400000);
            return Stories.Where(s => s.ID > num).Take(10);
        }

        public string Sitemap()
        {
            var allMoods = AllMoods();
            XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";

            const string url = "http://www.ilovethismusic.com/Song/Detail/";
            const string artistUrl = "http://www.ilovethismusic.com/artist/";
            const string categoryUrl = "http://www.ilovethismusic.com/Song/Category/";
            const string categoryWeatherUrl = "http://www.ilovethismusic.com/Song/CategoryWeather/";
            const string searchUrl = "http://www.ilovethismusic.com/Song/Search/";

            string moodUrl = "http://www.ilovethismusic.com/Song/Search/{0}/{1}/Mood";

            var categories = Categories;
            var sitemap = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),

                new XElement(ns + "urlset",
                    new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "1.00")),

                                new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Search?q=jane+my+daughter&searchType=Expression"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.80")),

                                new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Search?q=this+year+i+am+getting+married+and+having+a+daughter&searchType=Expression"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.80")),

                                new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Search?q=show+me+the+money&searchType=Expression"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.80")),



                   from mood in AllMoods()
                   select
                           new XElement(ns + "url",
                               new XElement(ns + "loc", string.Format(moodUrl, mood.mood, mood.counter)),
                               new XElement(ns + "changefreq", "monthly"),
                               new XElement(ns + "priority", "0.80")
                     ),
                    new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/CategoryWeather"),
                                new XElement(ns + "changefreq", "daily"),
                                new XElement(ns + "priority", "0.80")),

                    new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Upcoming/1"),
                                new XElement(ns + "changefreq", "daily"),
                                new XElement(ns + "priority", "0.80")),
                    from category in Categories.OrderBy(s => s.ID)
                    select
                    new XElement(ns + "url",
                                new XElement(ns + "loc", categoryUrl + category.Name.Replace("&", "amp").Replace("/", "fws").Replace(" ", "_") + "/1"),
                                new XElement(ns + "changefreq", "daily"),
                                new XElement(ns + "priority", "0.70")),
                    from category in Categories.OrderBy(s => s.ID)
                    select
                    new XElement(ns + "url",
                                new XElement(ns + "loc", categoryWeatherUrl + category.Name.Replace("&", "amp").Replace("/", "fws").Replace(" ", "_") + "/1"),
                                new XElement(ns + "changefreq", "daily"),
                                new XElement(ns + "priority", "0.70")),
                    from story in Get50Songs()
                    select
                            new XElement(ns + "url",
                                new XElement(ns + "loc", url + story.id),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.50")
                      ),
                      from artist in Get50Artist()
                      select
                              new XElement(ns + "url",
                                  new XElement(ns + "loc", artistUrl + artist.mood.Replace(" ", "+")),
                                  new XElement(ns + "changefreq", "monthly"),
                                  new XElement(ns + "priority", "0.80")
                        ),

                      new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Tag/music/1"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.30"))
                  ,
                  new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Tag/Sexy/1"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.30"))
                  ,
                        new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/PostedBy/musicman/1"),
                                new XElement(ns + "changefreq", "monthly"),
                                new XElement(ns + "priority", "0.30"))
                  ,
                      new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/About/"),
                                new XElement(ns + "changefreq", "yearly"),
                                new XElement(ns + "priority", "0.40")),
                       new XElement(ns + "url",
                                new XElement(ns + "loc", "http://www.ilovethismusic.com/Song/Contact/"),
                                new XElement(ns + "changefreq", "yearly"),
                                new XElement(ns + "priority", "0.40"))
                  )
                );
            return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + sitemap.ToString();
        }

        private IEnumerable<ARTIST> Get10Artists()
        {
            Random random = new Random();
            int num = random.Next(36379);
            return ARTISTs.Skip(num).Take(10);
        }

        #endregion

        #region LalaHelpers

        public IEnumerable<Story> GetStoriesForStack(int take)
        {
            return Stories.Where(s => s.Status == 0).Take(take);
        }

        public IEnumerable<Story> GetStoriesNotUpdatedSkip(int skip)
        {
            return Stories.Where(s => s.Status == 0).Skip(skip).Take(1000);
        }

        public IEnumerable<Story> GetStoriesNotUpdatedSkip(int skip, int take)
        {
            return Stories.Where(s => s.Status == 0).Skip(skip).Take(take);
        }

        public List<Story> GetAllStoriesForCategoryID(int categoryID)
        {
            return Stories.Where(s => s.CategoryID == categoryID).ToList();
        }

        public IEnumerable<Story> GetStoriesNotUpdated()
        {
            return Stories.Where(s => s.Status == 0).Take(3000).OrderBy(v => v.ID).ToList();
        }

        public IEnumerable<Story> GetStoriesNotUpdatedSortedBack()
        {
            return Stories.Where(s => s.Status == 0).Take(3000).OrderByDescending(v => v.ID).ToList();
        }

        public IEnumerable<Story> GetStoriesNotUpdatedSortedBackSkip()
        {
            return Stories.Where(s => s.Status == 0).Skip(3000).Take(3000).OrderByDescending(v => v.ID).ToList();
        }

        public void SubmitSongWithMp3AndVideo(int storyID, List<String> mp3List, string encodingCode, string videoID, string tags, string youTubeDescrption)
        {
            try
            {
                using (var ts = new TransactionScope())
                {
                    var now = DateTime.UtcNow;

                    var story = Stories.Where(s => s.ID == storyID).SingleOrDefault();

                    story.YouTubeID = videoID.Trim();
                    story.youTubeDescription = youTubeDescrption.Trim();

                    SubmitChanges();

                    #region mp3Files

                    int counterMp3 = 1;

                    foreach (string mp3Url in mp3List)
                    {
                        if (mp3Url.Length < 512)
                        {
                            MP3FILE mp3FileObject = new MP3FILE
                            {
                                Story_ID = story.ID,
                                url = mp3Url,
                                IsValid = true,
                                Title = WebHelper.CreateAmper(story.Title) + " - " + WebHelper.CreateAmper(story.ArtistName),
                                DateCreated = DateTime.Now,
                                Count = counterMp3
                            };
                            MP3FILEs.InsertOnSubmit(mp3FileObject);
                            counterMp3++;
                        }
                    }

                    #endregion

                    #region Votes

                    story.PublishedOn = new DateTime(2006, 4, 7, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);

                    #endregion Votes

                    story.Status = 1;
                    SubmitChanges();
                    ts.Complete();
                }
            }
            catch (Exception e)
            {
                throw e;
            }

            try
            {
                using (var ts = new TransactionScope())
                {
                    #region Tags

                    int numberOfTags = StoryTags.Where(s => s.StoryID == storyID).Count();
                    if (numberOfTags == 0)
                    {
                        if (!string.IsNullOrEmpty(tags))
                        {
                            var tagsArray = tags.Split(',');

                            if (tagsArray.Length > 0)
                            {
                                var newTags = new List<Tag>();
                                var allTags = new List<Tag>();

                                for (var i = 0; i < tagsArray.Length; i++)
                                {
                                    var tagName = tagsArray[i].Trim();
                                    if (tagName.Length > 0)
                                    {
                                        if (tagName.Length > 64)
                                            tagName = tagName.Substring(0, 64);
                                        var tag = Tags.FirstOrDefault(t => t.Name == tagName);

                                        if (tag == null)
                                        {
                                            tag = new Tag { Name = tagName };
                                            newTags.Add(tag);
                                        }

                                        allTags.Add(tag);
                                    }
                                }

                                if (newTags.Count > 0)
                                {
                                    Tags.InsertAllOnSubmit(newTags);
                                    SubmitChanges();
                                }

                                if (allTags.Count > 0)
                                {
                                    var storyTags = new List<StoryTag>();

                                    for (var i = 0; i < allTags.Count; i++)
                                    {
                                        storyTags.Add(new StoryTag { StoryID = storyID, TagID = allTags[i].ID });
                                    }

                                    StoryTags.InsertAllOnSubmit(storyTags);
                                    SubmitChanges();
                                }
                            }
                        }
                    }

                    #endregion Tags

                    ts.Complete();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<Story> GetAllSongs()
        {
            return Stories;
        }

        public void InsertImage(IMAGE item)
        {
            IMAGEs.InsertOnSubmit(item);
        }

        public IMAGE GetImage(int imageID)
        {
            return IMAGEs.Where(s => s.IMAGE_IDZ == imageID).SingleOrDefault();
        }

        public void SetArtistStatus(int artistID, int status)
        {
            using (var ts = new TransactionScope())
            {
                ARTIST artist = ARTISTs.Where(s => s.ARTIST_IDZ == artistID).SingleOrDefault();
                artist.status = status;
                SubmitChanges();
                ts.Complete();
            }

        }

        #endregion

        public void Save()
        {
            SubmitChanges();
        }


    }
}